/*
 * @Author: 0x9DEFA478
 * @Date: 2021-10-09 17:40:56
 * @LastEditTime: 2021-10-11 16:11:52
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "MFRC522.h"
#include "MFRC522_Register.h"



#define vMFRC522_PICC_CMD_AUTHENT1A                 0x60U              //验证A密钥
#define vMFRC522_PICC_CMD_AUTHENT1B                 0x61U              //验证B密钥



//============================================================================================================================================
//
// 底层方法
//
//============================================================================================================================================

//读取寄存器 返回寄存器值
static Hbyte SPI_ReadReg(MFRC522* _this,Hbyte Addr){
  Hbyte* tx;
  Hbyte* rx;

  tx=_this->TxSequenceBuffer;
  rx=_this->RxSequenceBuffer;

  tx[0]=((Addr<<1)&0x7EU)|0x80U;
  tx[1]=0x00U;

  _this->LL_Function.TransferSequence.Transfer_SPI(tx,rx,2,_this->LL_Speed);

  return rx[1];
}

//重复读取寄存器若干次
static void SPI_ReReadRegToArray(MFRC522* _this,Hbyte Addr,Hbyte* dst,int Length){
  Hbyte* tx;
  Hbyte* rx;
  int i;

  tx=_this->TxSequenceBuffer;
  rx=_this->RxSequenceBuffer;

  Addr=((Addr<<1)&0x7EU)|0x80U;
  for(i=0;i<Length;i++){
    tx[i]=Addr;
  }
  tx[i]=0x00U;

  _this->LL_Function.TransferSequence.Transfer_SPI(tx,rx,Length+1,_this->LL_Speed);

  for(i=0;i<Length;i++){
    dst[i]=rx[1+i];
  }

}

//读取多个连续的寄存器
static void SPI_ReadRegArray(MFRC522* _this,Hbyte Addr,Hbyte* dst,int Length){
  Hbyte* tx;
  Hbyte* rx;
  int i;

  tx=_this->TxSequenceBuffer;
  rx=_this->RxSequenceBuffer;

  for(i=0;i<Length;i++){
    tx[i]=((Addr<<1)&0x7EU)|0x80U;
    Addr++;
  }
  tx[i]=0x00U;

  _this->LL_Function.TransferSequence.Transfer_SPI(tx,rx,Length+1,_this->LL_Speed);

  for(i=0;i<Length;i++){
    dst[i]=rx[1+i];
  }
  
}

//写寄存器
static void SPI_WriteReg(MFRC522* _this,Hbyte Addr,Hbyte data){
  Hbyte* tx;
  Hbyte* rx;

  tx=_this->TxSequenceBuffer;
  rx=_this->RxSequenceBuffer;

  tx[0]=((Addr<<1)&0x7EU);
  tx[1]=data;

  _this->LL_Function.TransferSequence.Transfer_SPI(tx,rx,2,_this->LL_Speed);
}

//重复写入寄存器若干次
static void SPI_ReWriteRegFromArray(MFRC522* _this,Hbyte Addr,Hbyte* src,int Length){
#if 1
  Hbyte* tx;
  Hbyte* rx;
  int i;

  tx=_this->TxSequenceBuffer;
  rx=_this->RxSequenceBuffer;

  tx[0]=((Addr<<1)&0x7EU);
  for(i=0;i<Length;i++){
    tx[i+1]=src[i];
  }

  _this->LL_Function.TransferSequence.Transfer_SPI(tx,rx,Length+1,_this->LL_Speed);
#else
  while(Length>0){
    Length--;
    SPI_WriteReg(_this,Addr,src[0]);
    src=&src[1];
  }
#endif
}

//写入多个连续的寄存器
static void SPI_WriteRegArray(MFRC522* _this,Hbyte Addr,Hbyte* src,int Length){
#if 0
  Hbyte* tx;
  Hbyte* rx;
  int i;

  tx=_this->TxSequenceBuffer;
  rx=_this->RxSequenceBuffer;

  tx[0]=((Addr<<1)&0x7EU);
  for(i=0;i<Length;i++){
    tx[i+1]=src[i];
  }

  _this->LL_Function.TransferSequence.Transfer_SPI(tx,rx,Length+1,_this->LL_Speed);
#else
  while(Length>0){
    Length--;
    SPI_WriteReg(_this,Addr,src[0]);
    src=&src[1];
    Addr++;
  }
#endif
}




//读取寄存器 返回寄存器值
static Hbyte IIC_ReadReg(MFRC522* _this,Hbyte Addr){
  Hbyte* tx;
  Hbyte* rx;

  tx=_this->TxSequenceBuffer;
  rx=_this->RxSequenceBuffer;

  tx[0]=Addr;

  _this->LL_Function.TransferSequence.Transfer_IIC.Read(_this->LL_Function.TransferSequence.Transfer_IIC.deviceAddr,tx,1,rx,1);

  return rx[0];
}

//重复读取寄存器若干次
static void IIC_ReReadRegToArray(MFRC522* _this,Hbyte Addr,Hbyte* dst,int Length){

  while(Length>0){
    Length--;
    dst[0]=IIC_ReadReg(_this,Addr);
    dst=&dst[1];
  }

}

//读取多个连续的寄存器
static void IIC_ReadRegArray(MFRC522* _this,Hbyte Addr,Hbyte* dst,int Length){
  Hbyte* tx;
  Hbyte* rx;
  int i;

  tx=_this->TxSequenceBuffer;
  rx=_this->RxSequenceBuffer;

  tx[0]=Addr;

  _this->LL_Function.TransferSequence.Transfer_IIC.Read(_this->LL_Function.TransferSequence.Transfer_IIC.deviceAddr,tx,1,rx,Length);

  for(i=0;i<Length;i++){
    dst[i]=rx[i];
  }
  
}

//写寄存器
static void IIC_WriteReg(MFRC522* _this,Hbyte Addr,Hbyte data){
  Hbyte* tx;

  tx=_this->TxSequenceBuffer;

  tx[0]=Addr;
  tx[1]=data;

  _this->LL_Function.TransferSequence.Transfer_IIC.Write(_this->LL_Function.TransferSequence.Transfer_IIC.deviceAddr,tx,2);

}

//重复写入寄存器若干次
static void IIC_ReWriteRegFromArray(MFRC522* _this,Hbyte Addr,Hbyte* src,int Length){

  while(Length>0){
    Length--;
    IIC_WriteReg(_this,Addr,src[0]);
    src=&src[1];
  }
}

//写入多个连续的寄存器
static void IIC_WriteRegArray(MFRC522* _this,Hbyte Addr,Hbyte* src,int Length){
  Hbyte* tx;
  int i;

  tx=_this->TxSequenceBuffer;

  tx[0]=Addr;
  for(i=0;i<Length;i++){
    tx[1+i]=src[i];
  }

  _this->LL_Function.TransferSequence.Transfer_IIC.Write(_this->LL_Function.TransferSequence.Transfer_IIC.deviceAddr,tx,Length+1);

}



//============================================================================================================================================
//
// 私有方法
//
//============================================================================================================================================

//修改寄存器某位段的值
static void RegModify(MFRC522* _this,Hbyte Addr,Hbyte Mask,Hbyte Value){
  Hbyte RegVal;

  RegVal=_this->StaticFunction.ReadReg(_this,Addr);
  RegVal=(RegVal&(~Mask))|(Value&Mask);
  _this->StaticFunction.WriteReg(_this,Addr,RegVal);
}

//停止当前命令并且清除状态位(可以用于通信操作之前)
static void ClearIrqStopCommand(MFRC522* _this){

  //停止正在操作的指令
  _this->StaticFunction.WriteReg(_this,vMFRC522_CommandReg,vMFRC522_Command_Idle);
  //清空标志位
  RegModify(_this,vMFRC522_ComIrqReg,vMFRC522_ComIrqReg_Set1,0U);
}

//刷新后写入数据到FIFO
static void FlushWriteFIFO(MFRC522* _this,Hbyte* Data,int Length){

  //Flush FIFO
  RegModify(_this,vMFRC522_FIFOLevelReg,vMFRC522_FIFOLevelReg_FlushBuffer,vMFRC522_FIFOLevelReg_FlushBuffer);
  _this->StaticFunction.ReWriteRegFromArray(_this,vMFRC522_FIFODataReg,Data,Length);
}

//读取FIFO
static void ReadFIFO(MFRC522* _this,Hbyte* Data,int Length){
  _this->StaticFunction.ReReadRegToArray(_this,vMFRC522_FIFODataReg,Data,Length);
}

//等待状态位 有其中一位为1时结束等待
static Hbyte WaitStatus(MFRC522* _this,Hbyte Addr,Hbyte WaitMsk,int WaitTime){
  Hbyte RegVal;
  
  RegVal=_this->StaticFunction.ReadReg(_this,Addr);
  while((WaitTime>0)&&((RegVal&WaitMsk)==0x00U)){
    WaitTime--;
    _this->LL_Function.Delay(1);
    RegVal=_this->StaticFunction.ReadReg(_this,Addr);
  }

  return RegVal;
}

//初始化寄存器
static void RegInit(MFRC522* _this){

  //ISO14443A
  if(_this->ProtocolType==vMFRC522_ProtocolType_ISO14443_A){

    RegModify(_this,vMFRC522_RFCfgReg,vMFRC522_RFCfgReg_RxGain_Msk,0x7U<<vMFRC522_RFCfgReg_RxGain_Pos);//接收48dB

    //发送接收之间冷却延时设置
    RegModify(_this,vMFRC522_RxSelReg,vMFRC522_RxSelReg_RxWait_Msk,0x01U<<vMFRC522_RxSelReg_RxWait_Pos);

    //调制发送信号为100%ASK
    _this->StaticFunction.WriteReg(_this,vMFRC522_TxASKReg,vMFRC522_TxASKReg_Force100ASK);
  }
  
}

static void Init(MFRC522* _this){

  _this->LL_Function.Reset();

  //预先获取版本号
  _this->Version=_this->StaticFunction.ReadReg(_this,vMFRC522_VersionReg);

  MFRC522_Reset(_this);

}


//============================================================================================================================================
//
// 提供给外部的方法
//
//============================================================================================================================================

/**
 * @brief 初始化RC522
 * @param _this 未使用的句柄
 * @param LL_Function 底层相关回调与信息
 * @param TxSequenceBuffer 底层发送缓存 长度vMFRC522_TxSequenceBufferLength字节
 * @param RxSequenceBuffer 底层接收缓存 长度vMFRC522_RxSequenceBufferLength字节
 * @param Type 协议类型 vMFRC522_ProtocolType_ISO14443_A可选
 * @return 返回执行结果
 */
int MFRC522_Init(MFRC522* _this,MFRC522_LL_Function* LL_Function,void* TxSequenceBuffer,void* RxSequenceBuffer,int ProtocolType){

  _this->LL_Function=LL_Function[0];
  _this->TxSequenceBuffer=TxSequenceBuffer;
  _this->RxSequenceBuffer=RxSequenceBuffer;
  _this->ProtocolType=ProtocolType;


  _this->LL_Speed=0;
  _this->MFCrypto1On=0;

  switch(LL_Function->Type){
    case vMFRC522_LL_Function_Type_SPI:
      _this->StaticFunction.ReadReg=SPI_ReadReg;
      _this->StaticFunction.ReReadRegToArray=SPI_ReReadRegToArray;
      _this->StaticFunction.ReadRegArray=SPI_ReadRegArray;
      _this->StaticFunction.WriteReg=SPI_WriteReg;
      _this->StaticFunction.ReWriteRegFromArray=SPI_ReWriteRegFromArray;
      _this->StaticFunction.WriteRegArray=SPI_WriteRegArray;
      break;
    case vMFRC522_LL_Function_Type_IIC:
      _this->StaticFunction.ReadReg=IIC_ReadReg;
      _this->StaticFunction.ReReadRegToArray=IIC_ReReadRegToArray;
      _this->StaticFunction.ReadRegArray=IIC_ReadRegArray;
      _this->StaticFunction.WriteReg=IIC_WriteReg;
      _this->StaticFunction.ReWriteRegFromArray=IIC_ReWriteRegFromArray;
      _this->StaticFunction.WriteRegArray=IIC_WriteRegArray;
      break;
    default:
      return -1;
  }

  Init(_this);

  return vMFRC522_Result_Ok;
}

/**
 * @brief 复位RC522 在通信出现错误时可以使用 复位后开启载波
 * @param _this RC522句柄
 * @return 无
 */
void MFRC522_Reset(MFRC522* _this){

  _this->StaticFunction.WriteReg(_this,vMFRC522_CommandReg,vMFRC522_Command_SoftReset);

  while((_this->StaticFunction.ReadReg(_this,vMFRC522_CommandReg)&vMFRC522_CommandReg_PowerDown)!=0x00U){
  }

  _this->LL_Speed=-1;
  RegInit(_this);
  _this->LL_Speed=0;

  //关闭Tx载波
  RegModify(_this,vMFRC522_TxControlReg,vMFRC522_TxControlReg_Tx1RFEn|vMFRC522_TxControlReg_Tx2RFEn,0x0U);
  _this->LL_Function.Delay(2);
  //开启Tx载波
  RegModify(_this,vMFRC522_TxControlReg,vMFRC522_TxControlReg_Tx1RFEn|vMFRC522_TxControlReg_Tx2RFEn,vMFRC522_TxControlReg_Tx1RFEn|vMFRC522_TxControlReg_Tx2RFEn);
  _this->LL_Function.Delay(2);

}

/**
 * @brief 向卡发送数据
 * @param _this RC522句柄
 * @param TxData 发送的数据指针
 * @param TxBitLength 发送的长度 单位Bit 低位在前
 * @param WaitTime 最大等待时间
 * @return 返回执行结果
 */
int MFRC522_Transmit(MFRC522* _this,Hbyte* TxData,Hbyte TxBitLength,int WaitTime){
  Hbyte ComIrqReg;
  Hbyte TxByteLength;
  Hbyte LastTxBitLength;


  TxByteLength=TxBitLength>>3;
  LastTxBitLength=TxBitLength&0x07U;
  if(LastTxBitLength!=0x00U){
    TxByteLength+=0x01U;
  }

  ClearIrqStopCommand(_this);
  FlushWriteFIFO(_this,TxData,TxByteLength);
  _this->StaticFunction.WriteReg(_this,vMFRC522_BitFramingReg,vMFRC522_BitFramingReg_TxLastBits_Msk&(LastTxBitLength<<vMFRC522_BitFramingReg_TxLastBits_Pos));//发送接收比特设置
  _this->StaticFunction.WriteReg(_this,vMFRC522_CommandReg,vMFRC522_Command_Transmit);//发送指令

  //等待通讯
  ComIrqReg=WaitStatus(_this,vMFRC522_ComIrqReg,vMFRC522_ComIrqReg_TxIRq|vMFRC522_ComIrqReg_ErrIRq,WaitTime);

  if((ComIrqReg&vMFRC522_ComIrqReg_ErrIRq)!=0x0U){
    //出现错误 已经无法继续通信
    return vMFRC522_Result_Error;
  }

  if((ComIrqReg&vMFRC522_ComIrqReg_TxIRq)==0x0U){
    //通信未完成 无法继续通信
    return vMFRC522_Result_Error;
  }

  return vMFRC522_Result_Ok;
}

/**
 * @brief 接收卡发来的数据
 * @param _this RC522句柄
 * @param RxData 容纳接收数据的空间指针
 * @param MaxRxBitLengthPtr 最大接收长度 单位Bit
 * @param RxBitLengthPtr 用于返回接收到的长度 单位Bit 低位在前
 * @param WaitTime 最大等待时间
 * @return 返回执行结果
 */
int MFRC522_Receive(MFRC522* _this,Hbyte* RxData,Hbyte MaxRxBitLengthPtr,Hbyte* RxBitLengthPtr,int WaitTime){
  Hbyte ComIrqReg;
  Hbyte RxByteLength;
  Hbyte LastRxBitLength;

  ClearIrqStopCommand(_this);
  RegModify(_this,vMFRC522_FIFOLevelReg,vMFRC522_FIFOLevelReg_FlushBuffer,vMFRC522_FIFOLevelReg_FlushBuffer);//Flush FIFO
  _this->StaticFunction.WriteReg(_this,vMFRC522_BitFramingReg,0x0U);//发送接收比特设置
  _this->StaticFunction.WriteReg(_this,vMFRC522_CommandReg,vMFRC522_Command_Receive);//接收指令

  //等待通讯
  ComIrqReg=WaitStatus(_this,vMFRC522_ComIrqReg,vMFRC522_ComIrqReg_RxIRq|vMFRC522_ComIrqReg_ErrIRq,WaitTime);

  if((ComIrqReg&vMFRC522_ComIrqReg_ErrIRq)!=0x0U){
    //出现错误 已经无法继续通信
    return vMFRC522_Result_Error;
  }

  if((ComIrqReg&vMFRC522_ComIrqReg_RxIRq)!=0x0U){
    //通信完成

    RxByteLength=_this->StaticFunction.ReadReg(_this,vMFRC522_FIFOLevelReg)&vMFRC522_FIFOLevelReg_FIFOLevel_Msk;
    LastRxBitLength=_this->StaticFunction.ReadReg(_this,vMFRC522_ControlReg)&vMFRC522_ControlReg_RxLastBits_Msk;

    if(RxByteLength>(vMFRC522_RxSequenceBufferLength-1)){
      //接收数据过长
      return vMFRC522_Result_RecvTooLong;
    }

    if(LastRxBitLength==0x00U){
      RxBitLengthPtr[0]=8*RxByteLength;
    }else{
      RxBitLengthPtr[0]=8*(RxByteLength-1)+LastRxBitLength;
    }

    if(RxBitLengthPtr[0]>MaxRxBitLengthPtr){
      //接收数据过长
      return vMFRC522_Result_RecvTooLong;
    }

    if(RxByteLength>0){
      ReadFIFO(_this,RxData,RxByteLength);
    }

  }else{
    //通信未完成
    return vMFRC522_Result_RecvTimeOut;
  }

  return vMFRC522_Result_Ok;
}

/**
 * @brief 发送后接收数据
 * @param _this RC522句柄
 * @param TxData 发送的数据指针 *这个空间可与RxData为同一个
 * @param TxBitLength 发送的长度 单位Bit 低位在前
 * @param RxData 容纳接收数据的空间指针 *这个空间可与RxData为同一个
 * @param MaxRxBitLengthPtr 最大接收长度 单位Bit
 * @param RxBitLengthPtr 用于返回接收到的长度 单位Bit 低位在前
 * @param WaitTime 最大等待时间
 * @return 返回执行结果
 */
int MFRC522_Transceive(MFRC522* _this,Hbyte* TxData,Hbyte TxBitLength,Hbyte* RxData,Hbyte MaxRxBitLengthPtr,Hbyte* RxBitLengthPtr,int WaitTime){
  Hbyte ComIrqReg;
  Hbyte TxByteLength;
  Hbyte LastTxBitLength;
  Hbyte RxByteLength;
  Hbyte LastRxBitLength;


  TxByteLength=TxBitLength>>3;
  LastTxBitLength=TxBitLength&0x07U;
  if(LastTxBitLength!=0x00U){
    TxByteLength+=0x01U;
  }

  ClearIrqStopCommand(_this);
  FlushWriteFIFO(_this,TxData,TxByteLength);
  _this->StaticFunction.WriteReg(_this,vMFRC522_BitFramingReg,vMFRC522_BitFramingReg_TxLastBits_Msk&(LastTxBitLength<<vMFRC522_BitFramingReg_TxLastBits_Pos));//发送接收比特设置
  _this->StaticFunction.WriteReg(_this,vMFRC522_CommandReg,vMFRC522_Command_Transceive);//发送接收指令
  RegModify(_this,vMFRC522_BitFramingReg,vMFRC522_BitFramingReg_StartSend,vMFRC522_BitFramingReg_StartSend);//启动发送

  //等待通讯
  ComIrqReg=WaitStatus(_this,vMFRC522_ComIrqReg,vMFRC522_ComIrqReg_RxIRq|vMFRC522_ComIrqReg_ErrIRq,WaitTime);

  if((ComIrqReg&vMFRC522_ComIrqReg_ErrIRq)!=0x0U){
    //出现错误 已经无法继续通信
    return vMFRC522_Result_Error;
  }

  if((ComIrqReg&vMFRC522_ComIrqReg_RxIRq)!=0x0U){
    //通信完成

    RxByteLength=_this->StaticFunction.ReadReg(_this,vMFRC522_FIFOLevelReg)&vMFRC522_FIFOLevelReg_FIFOLevel_Msk;
    LastRxBitLength=_this->StaticFunction.ReadReg(_this,vMFRC522_ControlReg)&vMFRC522_ControlReg_RxLastBits_Msk;

    if(RxByteLength>(vMFRC522_RxSequenceBufferLength-1)){
      //接收数据过长
      return vMFRC522_Result_RecvTooLong;
    }

    if(LastRxBitLength==0x00U){
      RxBitLengthPtr[0]=8*RxByteLength;
    }else{
      RxBitLengthPtr[0]=8*(RxByteLength-1)+LastRxBitLength;
    }

    if(RxBitLengthPtr[0]>MaxRxBitLengthPtr){
      //接收数据过长
      return vMFRC522_Result_RecvTooLong;
    }

    if(RxByteLength>0){
      ReadFIFO(_this,RxData,RxByteLength);
    }

  }else{
    //通信未完成
    if((ComIrqReg&vMFRC522_ComIrqReg_TxIRq)!=0x0U){
      //仅发送完成
      return vMFRC522_Result_NoCard;
    }else{
      //发送未完成 无法继续通信
      return vMFRC522_Result_Error;
    }
  }

  return vMFRC522_Result_Ok;
}

/**
 * @brief 进行三轮认证
 * @param _this RC522句柄
 * @param SerialNumber 卡ID
 * @param BlockAddr 要验证的块地址
 * @param AuthentType 要验证的密码类型 vMFRC522_MFAuthent_AuthentType_A与vMFRC522_MFAuthent_AuthentType_B可选
 * @param Password 密码序列
 * @return 返回执行结果
 */
int MFRC522_MFAuthent(MFRC522* _this,Hbyte* SerialNumber,Hbyte BlockAddr,int AuthentType,Hbyte* Password){
  Hbyte TxRxBuffer[vMFRC522_RxSequenceBufferLength];
  Hbyte ComIrqReg;

  switch(AuthentType){
    case vMFRC522_MFAuthent_AuthentType_A:
      break;
    case vMFRC522_MFAuthent_AuthentType_B:
      break;
    default:
      return vMFRC522_Result_ParamError;
  }

  if(AuthentType==vMFRC522_MFAuthent_AuthentType_A){
    TxRxBuffer[0]=vMFRC522_PICC_CMD_AUTHENT1A;
  }else{
    TxRxBuffer[0]=vMFRC522_PICC_CMD_AUTHENT1B;
  }

  TxRxBuffer[1]=BlockAddr;

  TxRxBuffer[2]=Password[0];
  TxRxBuffer[3]=Password[1];
  TxRxBuffer[4]=Password[2];
  TxRxBuffer[5]=Password[3];
  TxRxBuffer[6]=Password[4];
  TxRxBuffer[7]=Password[5];

  TxRxBuffer[8]=SerialNumber[0];
  TxRxBuffer[9]=SerialNumber[1];
  TxRxBuffer[10]=SerialNumber[2];
  TxRxBuffer[11]=SerialNumber[3];

  ClearIrqStopCommand(_this);
  FlushWriteFIFO(_this,TxRxBuffer,12);
  _this->StaticFunction.WriteReg(_this,vMFRC522_BitFramingReg,0U);//发送接收比特设置
  _this->StaticFunction.WriteReg(_this,vMFRC522_CommandReg,vMFRC522_Command_MFAuthent);//开始密钥认证

  //等待通讯
  ComIrqReg=WaitStatus(_this,vMFRC522_ComIrqReg,vMFRC522_ComIrqReg_IdleIRq|vMFRC522_ComIrqReg_ErrIRq,10);

  if((ComIrqReg&vMFRC522_ComIrqReg_ErrIRq)!=0x0U){
    //出现错误 已经无法继续通信
    return vMFRC522_Result_Error;
  }

  if((ComIrqReg&vMFRC522_ComIrqReg_IdleIRq)==0x0U){
    //无响应 已经无法继续通信
    return vMFRC522_Result_Error;
  }

  if((_this->StaticFunction.ReadReg(_this,vMFRC522_Status2Reg)&vMFRC522_Status2Reg_MFCrypto1On)==0){
    //密码验证失败
    return vMFRC522_Result_Error;
  }
  
  return vMFRC522_Result_Ok;
}

/**
 * @brief 清除MFCrypto1On位 对一张卡处理完成后调用一次(清除加密状态)
 * @param _this RC522句柄
 * @return 无
 */
void MFRC522_ClearMFCrypto1On(MFRC522* _this){

  RegModify(_this,vMFRC522_Status2Reg,vMFRC522_Status2Reg_MFCrypto1On,0);
}

//============================================================================================================================================
//
// 提供给外部的方法(不一定是顶层必要的方法)
//
//============================================================================================================================================

/**
 * @brief 获取RC522版本号 可使用这个方法判定RC522是否存在
 * @param _this RC522句柄
 * @return 版本号
 */
Hbyte MFRC522_Version(MFRC522* _this){

  //预先获取版本号
  return _this->StaticFunction.ReadReg(_this,vMFRC522_VersionReg);
}

/**
 * @brief 验证RC522是否存在
 * @param _this RC522句柄
 * @return 返回执行结果
 */
int MFRC522_IsExist(MFRC522* _this){

  if(_this->Version==MFRC522_Version(_this)){

    return vMFRC522_Result_Ok;
  }

  return vMFRC522_Result_Error;
}

/**
 * @brief 设置RC522载波状态 可在空闲时关闭载波 节省能源消耗
 * @param _this RC522句柄
 * @param IsEn 是否使能载波
 * @return 无
 */
void MFRC522_SetTxStatus(MFRC522* _this,int IsEn){

  if(IsEn==0){
    //关闭Tx载波
    RegModify(_this,vMFRC522_TxControlReg,vMFRC522_TxControlReg_Tx1RFEn|vMFRC522_TxControlReg_Tx2RFEn,0x0U);
    _this->LL_Function.Delay(2);
  }else{
    //开启Tx载波
    RegModify(_this,vMFRC522_TxControlReg,vMFRC522_TxControlReg_Tx1RFEn|vMFRC522_TxControlReg_Tx2RFEn,vMFRC522_TxControlReg_Tx1RFEn|vMFRC522_TxControlReg_Tx2RFEn);
    _this->LL_Function.Delay(2);
  }
}
